#ifndef RECOVERYMANAGER_H_
#define RECOVERYMANAGER_H_

#include <cstring>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <semaphore.h>

using namespace std;

#include "../exception/InitializationException.h"
#include "../Redundancy/CRCBlocks.h"
#include "../Redundancy/CRCWorker.h"
#include "../Redundancy/CRCFinishListener.h"
#include "../util/Lista_Cresc.h"
#include "../util/XORByteArray.h"

using namespace ::miniprojeto::Redundancy;

using namespace ::miniprojeto::excpetion;

using namespace ::miniprojeto::util;

namespace miniprojeto {
namespace recovery {

class RecoveryManager : public CRCFinishListener {
private:
	sem_t semWaitWorkers; /* semafaro para esperar o termino dos workers */
	sem_t mutex; /* semafaro de exclusão mutua */
	
	Lista_Cresc<CRCBlocks*>* blocksList; /*lalal*/
	
	string redundancyFile, outputFile;
	unsigned long fileLen;
	int blocksCount;
	int failures;
	int corrompedBlockIndex;
	int waitingWorkers;
	
	ifstream in;
	ofstream out;
	
	void openFiles();
	void setWorkersCreated(int nWorkers);
	void writeBlocks();
	void ignoreXorBlock();	
	void waitWorkersFinished();
	bool hasFailures();
	bool isRecuperable();
	void recovery();
	
public:
	
	static const unsigned int BLOCK_SIZE = 4096;
	
	virtual void recevFinishWorkNotification(void* worker);
	
	RecoveryManager();
	void setTargetFile(string fName);
	void init();
	virtual ~RecoveryManager();
};

}

}

#endif /*RECOVERYMANAGER_H_*/
